﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Mrkz.ImageManipulation.SpatialFiltering
{
    /// <summary>
    /// this filter alter the brightness of the output image with a vignette effect
    /// </summary>
    public class LinearVignetteFilter : ParametricFilterKernelBase
    {
        float _intensity;
        public LinearVignetteFilter(float Intensity) : base()
        {
            _intensity = Intensity;
        }

        public override SpatialFilterKernel ApplyToSpatialFilter(SpatialFilterKernel InputFilter, SpatialFilterEngineState stateObject)
        {
            int relC = stateObject.CurrentColumn - (stateObject.Width / 2);
            int relR = stateObject.CurrentRow - (stateObject.Height / 2);

            float radius =(float) Math.Sqrt(Math.Pow(relC,2)+Math.Pow(relR,2));
            float maxradius = (float)Math.Sqrt( Math.Pow(stateObject.Width/2,2) + Math.Pow(stateObject.Height/2,2));

            float f = 1-(radius / maxradius);
            
            return InputFilter*f;            
        }
        
    }

    public class AbruptVignetteFilter : ParametricFilterKernelBase
    {
        float _vignette_radius;
        public AbruptVignetteFilter(float radius)
            : base()
        {
            _vignette_radius = radius;
        }

        public override SpatialFilterKernel ApplyToSpatialFilter(SpatialFilterKernel InputFilter, SpatialFilterEngineState stateObject)
        {
            int relC = stateObject.CurrentColumn - (stateObject.Width / 2);
            int relR = stateObject.CurrentRow - (stateObject.Height / 2);

            float radius = (float)Math.Sqrt(Math.Pow(relC, 2) + Math.Pow(relR, 2));
            float maxradius = (float)Math.Sqrt(Math.Pow(stateObject.Width / 2, 2) + Math.Pow(stateObject.Height / 2, 2));

            if (radius > (maxradius*_vignette_radius))
                return InputFilter * 0;
            else
                return InputFilter;
        }

    }

    public class PowVignetteFilter : ParametricFilterKernelBase
    {
        float _intensity;
        public PowVignetteFilter(float Intensity)
            : base()
        {
            _intensity = Intensity;
        }

        public override SpatialFilterKernel ApplyToSpatialFilter(SpatialFilterKernel InputFilter, SpatialFilterEngineState stateObject)
        {
            int relC = stateObject.CurrentColumn - (stateObject.Width / 2);
            int relR = stateObject.CurrentRow - (stateObject.Height / 2);

            float radius = (float)Math.Sqrt(Math.Pow(relC, 2) + Math.Pow(relR, 2));
            float maxradius = (float)Math.Sqrt(Math.Pow(stateObject.Width / 2, 2) + Math.Pow(stateObject.Height / 2, 2));
           
            float f = (float)(1- Math.Pow((radius / maxradius),_intensity));

            return InputFilter * f;

        }       
    }

    public class InversePowVignetteFilter : ParametricFilterKernelBase
    {
        float _intensity;
        public InversePowVignetteFilter(float Intensity)
            : base()
        {
            _intensity = Intensity;
        }

        public override SpatialFilterKernel ApplyToSpatialFilter(SpatialFilterKernel InputFilter, SpatialFilterEngineState stateObject)
        {
            int relC = stateObject.CurrentColumn - (stateObject.Width / 2);
            int relR = stateObject.CurrentRow - (stateObject.Height / 2);

            float radius = (float)Math.Sqrt(Math.Pow(relC, 2) + Math.Pow(relR, 2));
            float maxradius = (float)Math.Sqrt(Math.Pow(stateObject.Width / 2, 2) + Math.Pow(stateObject.Height / 2, 2));

            float f = (float)(Math.Pow((radius / maxradius), _intensity));

            return InputFilter * f;

        }
    }
}
